package com.mallcai.bigdata.ladon.utils;

import com.mallcai.bigdata.ladon.dpl.vo.DataType;
import org.apache.commons.lang3.StringUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 解析表达式
 * Created by oneape<oneape15@163.com>
 * Created 2019-08-02 14:23.
 * Modify:
 */
public class AnalysisExpressionUtils {

    private static final String RULE_SET = "SET";
    private static final String RULE_ADD = "ADD";
    private static final String YEAR     = "YEARS";
    private static final String MONTH    = "MONTHS";
    private static final String DAY      = "DAYS";
    private static final String QUARTER  = "QUARTERS";
    private static final String WEEK     = "WEEKS";

    /**
     * 将日期表达式转换成相应的日期
     *
     * @param defaultValue   String 日期表达式
     * @param needDefaultVal boolean 是否需要默认值(当前日期)
     * @return Date
     */
    public static Date getDefaultValueDate(String defaultValue, boolean needDefaultVal) {
        Date date = getDefaultValueDate(defaultValue);
        if (needDefaultVal && date == null) {
            return new Date();
        }

        return date;
    }

    /**
     * 将默认值转换成相应的Date
     * ADD 1 DAYS     当前日期增加一天
     * ADD 1 WEEKS    当前日期增加一个星期
     * ADD 1 MONTHS   当前日期增加一个月
     * ADD 1 QUARTERS 当前日期增加一个季度
     * ADD 1 YEARS    当前日期增加一年
     * ADD -1 DAYS    当前日期减少一天
     * <p>
     * SET 1 WEEKS     设置本月第一个星期
     * SET 1 MONTHS
     *
     * @param defaultValue String 默认值规则
     * @return Date 如果格式不正确,则返回null
     */
    public static Date getDefaultValueDate(String defaultValue) {
        if (StringUtils.isBlank(defaultValue)) {
            defaultValue = "";
        }
        defaultValue = StringUtils.trim(defaultValue);
        String upperValue = StringUtils.upperCase(defaultValue);
        String[] rules = StringUtils.split(upperValue, " "); //按空隔切分字符串
        if (rules == null || rules.length != 3) {
            //判断是否为固定的某个日期,如果规则不正确,是直接返回空
            return DateUtils.parseDate(defaultValue, DateUtils.DATE_FORMAT_DATE);
        }
        int offset;
        try {
            offset = Integer.parseInt(rules[1]);
        } catch (NumberFormatException e) {
            //转换数字错误,直接返回空
            return null;
        }
        String unit = rules[2]; //单位

        //从当前日期开始
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(new Date());
        if (StringUtils.equals(RULE_ADD, rules[0])) {
            switch (unit) {
                case DAY:
                    calendar.add(Calendar.DAY_OF_MONTH, offset);
                    break;
                case WEEK:
                    calendar.add(Calendar.WEEK_OF_MONTH, offset);
                    break;
                case MONTH:
                    calendar.add(Calendar.MONTH, offset);
                    break;
                case QUARTER:
                    calendar.add(Calendar.MONTH, offset * 3);
                    break;
                case YEAR:
                    calendar.add(Calendar.YEAR, offset);
                    break;
                default:
                    return null;
            }
        } else if (StringUtils.equals(RULE_SET, rules[0])) {
            switch (unit) {
                case DAY:
                    calendar.add(Calendar.DAY_OF_MONTH, offset);
                    break;
                case WEEK:
                    calendar.add(Calendar.WEEK_OF_MONTH, offset);
                    calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); //偏移星期的星期
                    break;
                case MONTH:
                    calendar.add(Calendar.MONTH, offset);
                    calendar.set(Calendar.DAY_OF_MONTH, 1); //偏移月份的第一天
                    break;
                case QUARTER:
                    int curMonth = calendar.get(Calendar.MONTH) + 1;
                    int curQrt = curMonth / 3 + (curMonth % 3 == 0 ? 0 : 1);
                    int plus = offset * 3;
                    calendar.set(Calendar.MONTH, curQrt * 3 - 2 - 1); //一月为0
                    calendar.add(Calendar.MONTH, plus);
                    calendar.set(Calendar.DAY_OF_MONTH, 1); //偏移季度的第一个月的1号
                    break;
                case YEAR:
                    calendar.add(Calendar.YEAR, offset);
                    calendar.set(Calendar.MONTH, 0);      //偏移年度的第一个月
                    calendar.set(Calendar.DAY_OF_MONTH, 1); //偏移年度的第一个月第一天
                    break;
                default:
                    return null;
            }
        }

        return calendar.getTime();
    }

    /**
     * 根据数据类型,获取默认值
     *
     * @param dataType String
     * @param data     String
     * @return String
     */
    public static String getDefaultValueToHtml(String dataType, String data, boolean needDefaultVal) {
        //日期时间类型
        if (StringUtils.equals(DataType.DATETIME.getCode(), dataType)) {
            Date date = getDefaultValueDate(data, needDefaultVal);
            if (date == null) {
                return "";
            }
            return DateUtils.formatDate(date, DateUtils.NORMAL_DATE_FORMAT);
        }
        // 日期类型
        else if (StringUtils.equals(DataType.DATE.getCode(), dataType)) {
            Date date = getDefaultValueDate(data, needDefaultVal);
            if (date == null) {
                return "";
            }
            return DateUtils.formatDate(date, DateUtils.DATE_FORMAT_DATE);
        }
        // 月份类型
        else if (StringUtils.equals(DataType.MONTH.getCode(), dataType)) {
            Date date = getDefaultValueDate(data, needDefaultVal);
            if (date == null) {
                return "";
            }
            return DateUtils.formatDate(date, DateUtils.DATE_MONTH);
        }
        // 年份类型
        else if (StringUtils.equals(DataType.YEAR.getCode(), dataType)) {
            Date date = getDefaultValueDate(data, needDefaultVal);
            if (date == null) {
                return "";
            }
            return DateUtils.formatDate(date, DateUtils.DATE_YEAR);
        }
        // 数字类型
        else if (StringUtils.equals(DataType.INTEGER.getCode(), dataType)) {
            return StringUtils.defaultString(data, "0");
        }
        // 字符串类型
        else if (StringUtils.equals(DataType.STRING.getCode(), dataType)) {
            return StringUtils.defaultString(data, "");
        }

        return StringUtils.defaultString(data, "");
    }
}
